package org.feng.framework.filter;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.feng.framework.support.RequestWrapper;
import org.feng.framework.support.ResponseWrapper;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 过滤器实现
 * 1.日志链路追踪
 * 2.请求头携带日志链路追踪唯一id
 * 3.返回值携带日志链路追踪唯一id
 *
 * @author feng
 */
@Component
public class LogFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) throws IOException {
        String requestId = IdUtil.fastSimpleUUID();
        RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request);
        //请求头链路追踪
        requestWrapper.addHeader("requestId", requestId);
        //日志链路追踪
        MDC.put("traceId", requestId);
        String result = "";
        try {
            ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) servletResponse);
            filterChain.doFilter(requestWrapper, responseWrapper);
            result = responseWrapper.getResponseData(StandardCharsets.UTF_8.name());
            JSONObject resultObject = JSON.parseObject(result);
            //返回值链路追踪
            if (ObjectUtil.isNotNull(resultObject)) {
                resultObject.put("requestId", requestId);
                result = JSON.toJSONString(resultObject);
                servletResponse.getOutputStream().write(result.getBytes());
            }
        } catch (Exception e) {
            servletResponse.getOutputStream().write(result.getBytes());
        } finally {
            MDC.clear();
        }
    }
}
